Rename GdkDevice[Manager]Core to GdkX11Device[Manager]Core
authorMatthias Clasen <mclasen@redhat.com>
Tue, 21 Dec 2010 04:59:07 +0000 (23:59 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 21 Dec 2010 17:07:09 +0000 (12:07 -0500)
This is mainly to avoid clash with the classes of the same
name in the quartz backend.

13 files changed:
gdk/x11/Makefile.am
gdk/x11/gdkdevice-core-x11.c [new file with mode: 0644]
gdk/x11/gdkdevice-core.c [deleted file]
gdk/x11/gdkdevice-core.h [deleted file]
gdk/x11/gdkdevicemanager-core-x11.c [new file with mode: 0644]
gdk/x11/gdkdevicemanager-core.c [deleted file]
gdk/x11/gdkdevicemanager-core.h [deleted file]
gdk/x11/gdkdevicemanager-x11.c
gdk/x11/gdkdevicemanager-xi.c
gdk/x11/gdkdevicemanager-xi.h
gdk/x11/gdkx.h
gdk/x11/gdkx11device-core.h [new file with mode: 0644]
gdk/x11/gdkx11devicemanager-core.h [new file with mode: 0644]

index b8f9e3e88885b5c7b370ffeb033162a37e5fa3cc..8b09b320dc05877b41a42bc6f25cf51582d82f60 100644 (file)
@@ -23,10 +23,8 @@ libgdk_x11_la_SOURCES =      \
        gdkasync.c              \
        gdkasync.h              \
        gdkcursor-x11.c         \
-       gdkdevice-core.h        \
-       gdkdevice-core.c        \
-       gdkdevicemanager-core.h \
-       gdkdevicemanager-core.c \
+       gdkdevice-core-x11.c    \
+       gdkdevicemanager-core-x11.c \
        gdkdevicemanager-x11.c  \
        gdkdisplaymanager-x11.c \
        gdkdisplay-x11.c        \
@@ -77,6 +75,8 @@ libgdkinclude_HEADERS =       \
 
 libgdkx11include_HEADERS =     \
        gdkx11cursor.h          \
+       gdkx11device-core.h     \
+       gdkx11devicemanager-core.h \
        gdkx11display.h         \
        gdkx11displaymanager.h  \
        gdkx11keys.h            \
diff --git a/gdk/x11/gdkdevice-core-x11.c b/gdk/x11/gdkdevice-core-x11.c
new file mode 100644 (file)
index 0000000..795cbb4
--- /dev/null
@@ -0,0 +1,600 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkx11device-core.h"
+
+#include "gdkinternals.h"
+#include "gdkwindow.h"
+#include "gdkprivate-x11.h"
+#include "gdkasync.h"
+
+static gboolean gdk_x11_device_core_get_history (GdkDevice       *device,
+                                                 GdkWindow       *window,
+                                                 guint32          start,
+                                                 guint32          stop,
+                                                 GdkTimeCoord  ***events,
+                                                 gint            *n_events);
+static void     gdk_x11_device_core_get_state   (GdkDevice       *device,
+                                                 GdkWindow       *window,
+                                                 gdouble         *axes,
+                                                 GdkModifierType *mask);
+static void     gdk_x11_device_core_set_window_cursor (GdkDevice *device,
+                                                       GdkWindow *window,
+                                                       GdkCursor *cursor);
+static void     gdk_x11_device_core_warp (GdkDevice *device,
+                                          GdkScreen *screen,
+                                          gint       x,
+                                          gint       y);
+static gboolean gdk_x11_device_core_query_state (GdkDevice        *device,
+                                                 GdkWindow        *window,
+                                                 GdkWindow       **root_window,
+                                                 GdkWindow       **child_window,
+                                                 gint             *root_x,
+                                                 gint             *root_y,
+                                                 gint             *win_x,
+                                                 gint             *win_y,
+                                                 GdkModifierType  *mask);
+static GdkGrabStatus gdk_x11_device_core_grab   (GdkDevice     *device,
+                                                 GdkWindow     *window,
+                                                 gboolean       owner_events,
+                                                 GdkEventMask   event_mask,
+                                                 GdkWindow     *confine_to,
+                                                 GdkCursor     *cursor,
+                                                 guint32        time_);
+static void          gdk_x11_device_core_ungrab (GdkDevice     *device,
+                                                 guint32        time_);
+static GdkWindow * gdk_x11_device_core_window_at_position (GdkDevice       *device,
+                                                           gint            *win_x,
+                                                           gint            *win_y,
+                                                           GdkModifierType *mask,
+                                                           gboolean         get_toplevel);
+static void      gdk_x11_device_core_select_window_events (GdkDevice       *device,
+                                                           GdkWindow       *window,
+                                                           GdkEventMask     event_mask);
+
+G_DEFINE_TYPE (GdkX11DeviceCore, gdk_x11_device_core, GDK_TYPE_DEVICE)
+
+static void
+gdk_x11_device_core_class_init (GdkX11DeviceCoreClass *klass)
+{
+  GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+  device_class->get_history = gdk_x11_device_core_get_history;
+  device_class->get_state = gdk_x11_device_core_get_state;
+  device_class->set_window_cursor = gdk_x11_device_core_set_window_cursor;
+  device_class->warp = gdk_x11_device_core_warp;
+  device_class->query_state = gdk_x11_device_core_query_state;
+  device_class->grab = gdk_x11_device_core_grab;
+  device_class->ungrab = gdk_x11_device_core_ungrab;
+  device_class->window_at_position = gdk_x11_device_core_window_at_position;
+  device_class->select_window_events = gdk_x11_device_core_select_window_events;
+}
+
+static void
+gdk_x11_device_core_init (GdkX11DeviceCore *device_core)
+{
+  GdkDevice *device;
+
+  device = GDK_DEVICE (device_core);
+
+  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
+  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
+}
+
+static gboolean
+impl_coord_in_window (GdkWindow *window,
+                     int        impl_x,
+                     int        impl_y)
+{
+  if (impl_x < window->abs_x ||
+      impl_x >= window->abs_x + window->width)
+    return FALSE;
+
+  if (impl_y < window->abs_y ||
+      impl_y >= window->abs_y + window->height)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+gdk_x11_device_core_get_history (GdkDevice      *device,
+                                 GdkWindow      *window,
+                                 guint32         start,
+                                 guint32         stop,
+                                 GdkTimeCoord ***events,
+                                 gint           *n_events)
+{
+  XTimeCoord *xcoords;
+  GdkTimeCoord **coords;
+  GdkWindow *impl_window;
+  int tmp_n_events;
+  int i, j;
+
+  impl_window = _gdk_window_get_impl_window (window);
+  xcoords = XGetMotionEvents (GDK_WINDOW_XDISPLAY (window),
+                              GDK_WINDOW_XID (impl_window),
+                              start, stop, &tmp_n_events);
+  if (!xcoords)
+    return FALSE;
+
+  coords = _gdk_device_allocate_history (device, tmp_n_events);
+
+  for (i = 0, j = 0; i < tmp_n_events; i++)
+    {
+      if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
+        {
+          coords[j]->time = xcoords[i].time;
+          coords[j]->axes[0] = xcoords[i].x - window->abs_x;
+          coords[j]->axes[1] = xcoords[i].y - window->abs_y;
+          j++;
+        }
+    }
+
+  XFree (xcoords);
+
+  /* free the events we allocated too much */
+  for (i = j; i < tmp_n_events; i++)
+    {
+      g_free (coords[i]);
+      coords[i] = NULL;
+    }
+
+  tmp_n_events = j;
+
+  if (tmp_n_events == 0)
+    {
+      gdk_device_free_history (coords, tmp_n_events);
+      return FALSE;
+    }
+
+  if (n_events)
+    *n_events = tmp_n_events;
+
+  if (events)
+    *events = coords;
+  else if (coords)
+    gdk_device_free_history (coords, tmp_n_events);
+
+  return TRUE;
+}
+
+static void
+gdk_x11_device_core_get_state (GdkDevice       *device,
+                               GdkWindow       *window,
+                               gdouble         *axes,
+                               GdkModifierType *mask)
+{
+  gint x_int, y_int;
+
+  gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+  if (axes)
+    {
+      axes[0] = x_int;
+      axes[1] = y_int;
+    }
+}
+
+static void
+gdk_x11_device_core_set_window_cursor (GdkDevice *device,
+                                       GdkWindow *window,
+                                       GdkCursor *cursor)
+{
+  Cursor xcursor;
+
+  if (!cursor)
+    xcursor = None;
+  else
+    xcursor = gdk_x11_cursor_get_xcursor (cursor);
+
+  XDefineCursor (GDK_WINDOW_XDISPLAY (window),
+                 GDK_WINDOW_XID (window),
+                 xcursor);
+}
+
+static void
+gdk_x11_device_core_warp (GdkDevice *device,
+                          GdkScreen *screen,
+                          gint       x,
+                          gint       y)
+{
+  Display *xdisplay;
+  Window dest;
+
+  xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
+  dest = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
+
+  XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
+}
+
+static gboolean
+gdk_x11_device_core_query_state (GdkDevice        *device,
+                                 GdkWindow        *window,
+                                 GdkWindow       **root_window,
+                                 GdkWindow       **child_window,
+                                 gint             *root_x,
+                                 gint             *root_y,
+                                 gint             *win_x,
+                                 gint             *win_y,
+                                 GdkModifierType  *mask)
+{
+  GdkDisplay *display;
+  GdkScreen *default_screen;
+  Window xroot_window, xchild_window;
+  int xroot_x, xroot_y, xwin_x, xwin_y;
+  unsigned int xmask;
+
+  display = gdk_window_get_display (window);
+  default_screen = gdk_display_get_default_screen (display);
+
+  if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
+    {
+      if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window),
+                          GDK_WINDOW_XID (window),
+                          &xroot_window,
+                          &xchild_window,
+                          &xroot_x, &xroot_y,
+                          &xwin_x, &xwin_y,
+                          &xmask))
+        return FALSE;
+    }
+  else
+    {
+      XSetWindowAttributes attributes;
+      Display *xdisplay;
+      Window xwindow, w;
+
+      /* FIXME: untrusted clients not multidevice-safe */
+      xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
+      xwindow = GDK_SCREEN_XROOTWIN (default_screen);
+
+      w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
+                         CopyFromParent, InputOnly, CopyFromParent,
+                         0, &attributes);
+      XQueryPointer (xdisplay, w,
+                     &xroot_window,
+                     &xchild_window,
+                     &xroot_x, &xroot_y,
+                     &xwin_x, &xwin_y,
+                     &xmask);
+      XDestroyWindow (xdisplay, w);
+    }
+
+  if (root_window)
+    *root_window = gdk_x11_window_lookup_for_display (display, xroot_window);
+
+  if (child_window)
+    *child_window = gdk_x11_window_lookup_for_display (display, xchild_window);
+
+  if (root_x)
+    *root_x = xroot_x;
+
+  if (root_y)
+    *root_y = xroot_y;
+
+  if (win_x)
+    *win_x = xwin_x;
+
+  if (win_y)
+    *win_y = xwin_y;
+
+  if (mask)
+    *mask = xmask;
+
+  return TRUE;
+}
+
+static GdkGrabStatus
+gdk_x11_device_core_grab (GdkDevice    *device,
+                          GdkWindow    *window,
+                          gboolean      owner_events,
+                          GdkEventMask  event_mask,
+                          GdkWindow    *confine_to,
+                          GdkCursor    *cursor,
+                          guint32       time_)
+{
+  GdkDisplay *display;
+  Window xwindow, xconfine_to;
+  gint status;
+
+  display = gdk_device_get_display (device);
+
+  xwindow = GDK_WINDOW_XID (window);
+
+  if (confine_to)
+    confine_to = _gdk_window_get_impl_window (confine_to);
+
+  if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
+    xconfine_to = None;
+  else
+    xconfine_to = GDK_WINDOW_XID (confine_to);
+
+#ifdef G_ENABLE_DEBUG
+  if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
+    status = GrabSuccess;
+  else
+#endif
+  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+    {
+      /* Device is a keyboard */
+      status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display),
+                              xwindow,
+                              owner_events,
+                              GrabModeAsync, GrabModeAsync,
+                              time_);
+    }
+  else
+    {
+      Cursor xcursor;
+      guint xevent_mask;
+      gint i;
+
+      /* Device is a pointer */
+      if (!cursor)
+        xcursor = None;
+      else
+        {
+          _gdk_x11_cursor_update_theme (cursor);
+          xcursor = gdk_x11_cursor_get_xcursor (cursor);
+        }
+
+      xevent_mask = 0;
+
+      for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
+        {
+          if (event_mask & (1 << (i + 1)))
+            xevent_mask |= _gdk_x11_event_mask_table[i];
+        }
+
+      /* We don't want to set a native motion hint mask, as we're emulating motion
+       * hints. If we set a native one we just wouldn't get any events.
+       */
+      xevent_mask &= ~PointerMotionHintMask;
+
+      status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display),
+                             xwindow,
+                             owner_events,
+                             xevent_mask,
+                             GrabModeAsync, GrabModeAsync,
+                             xconfine_to,
+                             xcursor,
+                             time_);
+    }
+
+  _gdk_x11_display_update_grab_info (display, device, status);
+
+  return _gdk_x11_convert_grab_status (status);
+}
+
+static void
+gdk_x11_device_core_ungrab (GdkDevice *device,
+                            guint32    time_)
+{
+  GdkDisplay *display;
+  gulong serial;
+
+  display = gdk_device_get_display (device);
+  serial = NextRequest (GDK_DISPLAY_XDISPLAY (display));
+
+  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+    XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
+  else
+    XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
+
+  _gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
+}
+
+static GdkWindow *
+gdk_x11_device_core_window_at_position (GdkDevice       *device,
+                                        gint            *win_x,
+                                        gint            *win_y,
+                                        GdkModifierType *mask,
+                                        gboolean         get_toplevel)
+{
+  GdkDisplay *display;
+  GdkScreen *screen;
+  Display *xdisplay;
+  GdkWindow *window;
+  Window xwindow, root, child, last;
+  int xroot_x, xroot_y, xwin_x, xwin_y;
+  unsigned int xmask;
+
+  last = None;
+  display = gdk_device_get_display (device);
+  screen = gdk_display_get_default_screen (display);
+
+  /* This function really only works if the mouse pointer is held still
+   * during its operation. If it moves from one leaf window to another
+   * than we'll end up with inaccurate values for win_x, win_y
+   * and the result.
+   */
+  gdk_x11_display_grab (display);
+
+  xdisplay = GDK_SCREEN_XDISPLAY (screen);
+  xwindow = GDK_SCREEN_XROOTWIN (screen);
+
+  if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
+    {
+      XQueryPointer (xdisplay, xwindow,
+                     &root, &child,
+                     &xroot_x, &xroot_y,
+                     &xwin_x, &xwin_y,
+                     &xmask);
+
+      if (root == xwindow)
+        xwindow = child;
+      else
+       xwindow = root;
+    }
+  else
+    {
+      gint i, screens, width, height;
+      GList *toplevels, *list;
+      Window pointer_window, root, child;
+      int rootx = -1, rooty = -1;
+      int winx, winy;
+      unsigned int xmask;
+
+      /* FIXME: untrusted clients case not multidevice-safe */
+      pointer_window = None;
+      screens = gdk_display_get_n_screens (display);
+
+      for (i = 0; i < screens; ++i)
+        {
+          screen = gdk_display_get_screen (display, i);
+          toplevels = gdk_screen_get_toplevel_windows (screen);
+          for (list = toplevels; list != NULL; list = g_list_next (list))
+            {
+              window = GDK_WINDOW (list->data);
+              xwindow = GDK_WINDOW_XID (window);
+              gdk_x11_display_error_trap_push (display);
+              XQueryPointer (xdisplay, xwindow,
+                             &root, &child,
+                             &rootx, &rooty,
+                             &winx, &winy,
+                             &xmask);
+              if (gdk_x11_display_error_trap_pop (display))
+                continue;
+              if (child != None)
+                {
+                  pointer_window = child;
+                  break;
+                }
+              gdk_window_get_geometry (window, NULL, NULL, &width, &height);
+              if (winx >= 0 && winy >= 0 && winx < width && winy < height)
+                {
+                  /* A childless toplevel, or below another window? */
+                  XSetWindowAttributes attributes;
+                  Window w;
+
+                  w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
+                                     CopyFromParent, InputOnly, CopyFromParent,
+                                     0, &attributes);
+                  XMapWindow (xdisplay, w);
+                  XQueryPointer (xdisplay, xwindow,
+                                 &root, &child,
+                                 &rootx, &rooty,
+                                 &winx, &winy,
+                                 &xmask);
+                  XDestroyWindow (xdisplay, w);
+                  if (child == w)
+                    {
+                      pointer_window = xwindow;
+                      break;
+                    }
+                }
+            }
+
+          g_list_free (toplevels);
+          if (pointer_window != None)
+            break;
+        }
+
+      xwindow = pointer_window;
+    }
+
+  while (xwindow)
+    {
+      last = xwindow;
+      gdk_x11_display_error_trap_push (display);
+      XQueryPointer (xdisplay, xwindow,
+                     &root, &xwindow,
+                     &xroot_x, &xroot_y,
+                     &xwin_x, &xwin_y,
+                     &xmask);
+      if (gdk_x11_display_error_trap_pop (display))
+        break;
+
+      if (get_toplevel && last != root &&
+          (window = gdk_x11_window_lookup_for_display (display, last)) != NULL &&
+          window->window_type != GDK_WINDOW_FOREIGN)
+        {
+          xwindow = last;
+          break;
+        }
+    }
+
+  gdk_x11_display_ungrab (display);
+
+  window = gdk_x11_window_lookup_for_display (display, last);
+
+  if (win_x)
+    *win_x = (window) ? xwin_x : -1;
+
+  if (win_y)
+    *win_y = (window) ? xwin_y : -1;
+
+  if (mask)
+    *mask = xmask;
+
+  return window;
+}
+
+static void
+gdk_x11_device_core_select_window_events (GdkDevice    *device,
+                                         GdkWindow    *window,
+                                         GdkEventMask  event_mask)
+{
+  GdkEventMask filter_mask, window_mask;
+  guint xmask = 0;
+  gint i;
+
+  window_mask = gdk_window_get_events (window);
+  filter_mask = (GDK_POINTER_MOTION_MASK &
+                 GDK_POINTER_MOTION_HINT_MASK &
+                 GDK_BUTTON_MOTION_MASK &
+                 GDK_BUTTON1_MOTION_MASK &
+                 GDK_BUTTON2_MOTION_MASK &
+                 GDK_BUTTON3_MOTION_MASK &
+                 GDK_BUTTON_PRESS_MASK &
+                 GDK_BUTTON_RELEASE_MASK &
+                 GDK_KEY_PRESS_MASK &
+                 GDK_KEY_RELEASE_MASK &
+                 GDK_ENTER_NOTIFY_MASK &
+                 GDK_LEAVE_NOTIFY_MASK &
+                 GDK_FOCUS_CHANGE_MASK &
+                 GDK_PROXIMITY_IN_MASK &
+                 GDK_PROXIMITY_OUT_MASK &
+                 GDK_SCROLL_MASK);
+
+  /* Filter out non-device events */
+  event_mask &= filter_mask;
+
+  /* Unset device events on window mask */
+  window_mask &= ~(filter_mask);
+
+  /* Combine masks */
+  event_mask |= window_mask;
+
+  for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
+    {
+      if (event_mask & (1 << (i + 1)))
+        xmask |= _gdk_x11_event_mask_table[i];
+    }
+
+  if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
+    xmask |= StructureNotifyMask | PropertyChangeMask;
+
+  XSelectInput (GDK_WINDOW_XDISPLAY (window),
+                GDK_WINDOW_XID (window),
+                xmask);
+}
diff --git a/gdk/x11/gdkdevice-core.c b/gdk/x11/gdkdevice-core.c
deleted file mode 100644 (file)
index 224c3ed..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gdkdevice-core.h"
-
-#include "gdkinternals.h"
-#include "gdkwindow.h"
-#include "gdkprivate-x11.h"
-#include "gdkasync.h"
-
-static gboolean gdk_device_core_get_history (GdkDevice      *device,
-                                             GdkWindow      *window,
-                                             guint32         start,
-                                             guint32         stop,
-                                             GdkTimeCoord ***events,
-                                             gint           *n_events);
-static void gdk_device_core_get_state (GdkDevice       *device,
-                                       GdkWindow       *window,
-                                       gdouble         *axes,
-                                       GdkModifierType *mask);
-static void gdk_device_core_set_window_cursor (GdkDevice *device,
-                                               GdkWindow *window,
-                                               GdkCursor *cursor);
-static void gdk_device_core_warp (GdkDevice *device,
-                                  GdkScreen *screen,
-                                  gint       x,
-                                  gint       y);
-static gboolean gdk_device_core_query_state (GdkDevice        *device,
-                                             GdkWindow        *window,
-                                             GdkWindow       **root_window,
-                                             GdkWindow       **child_window,
-                                             gint             *root_x,
-                                             gint             *root_y,
-                                             gint             *win_x,
-                                             gint             *win_y,
-                                             GdkModifierType  *mask);
-static GdkGrabStatus gdk_device_core_grab   (GdkDevice     *device,
-                                             GdkWindow     *window,
-                                             gboolean       owner_events,
-                                             GdkEventMask   event_mask,
-                                             GdkWindow     *confine_to,
-                                             GdkCursor     *cursor,
-                                             guint32        time_);
-static void          gdk_device_core_ungrab (GdkDevice     *device,
-                                             guint32        time_);
-static GdkWindow * gdk_device_core_window_at_position (GdkDevice       *device,
-                                                       gint            *win_x,
-                                                       gint            *win_y,
-                                                       GdkModifierType *mask,
-                                                       gboolean         get_toplevel);
-static void      gdk_device_core_select_window_events (GdkDevice       *device,
-                                                       GdkWindow       *window,
-                                                       GdkEventMask     event_mask);
-
-
-G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE)
-
-static void
-gdk_device_core_class_init (GdkDeviceCoreClass *klass)
-{
-  GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
-
-  device_class->get_history = gdk_device_core_get_history;
-  device_class->get_state = gdk_device_core_get_state;
-  device_class->set_window_cursor = gdk_device_core_set_window_cursor;
-  device_class->warp = gdk_device_core_warp;
-  device_class->query_state = gdk_device_core_query_state;
-  device_class->grab = gdk_device_core_grab;
-  device_class->ungrab = gdk_device_core_ungrab;
-  device_class->window_at_position = gdk_device_core_window_at_position;
-  device_class->select_window_events = gdk_device_core_select_window_events;
-}
-
-static void
-gdk_device_core_init (GdkDeviceCore *device_core)
-{
-  GdkDevice *device;
-
-  device = GDK_DEVICE (device_core);
-
-  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
-  _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
-}
-
-static gboolean
-impl_coord_in_window (GdkWindow *window,
-                     int        impl_x,
-                     int        impl_y)
-{
-  if (impl_x < window->abs_x ||
-      impl_x >= window->abs_x + window->width)
-    return FALSE;
-
-  if (impl_y < window->abs_y ||
-      impl_y >= window->abs_y + window->height)
-    return FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-gdk_device_core_get_history (GdkDevice      *device,
-                             GdkWindow      *window,
-                             guint32         start,
-                             guint32         stop,
-                             GdkTimeCoord ***events,
-                             gint           *n_events)
-{
-  XTimeCoord *xcoords;
-  GdkTimeCoord **coords;
-  GdkWindow *impl_window;
-  int tmp_n_events;
-  int i, j;
-
-  impl_window = _gdk_window_get_impl_window (window);
-  xcoords = XGetMotionEvents (GDK_WINDOW_XDISPLAY (window),
-                              GDK_WINDOW_XID (impl_window),
-                              start, stop, &tmp_n_events);
-  if (!xcoords)
-    return FALSE;
-
-  coords = _gdk_device_allocate_history (device, tmp_n_events);
-
-  for (i = 0, j = 0; i < tmp_n_events; i++)
-    {
-      if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
-        {
-          coords[j]->time = xcoords[i].time;
-          coords[j]->axes[0] = xcoords[i].x - window->abs_x;
-          coords[j]->axes[1] = xcoords[i].y - window->abs_y;
-          j++;
-        }
-    }
-
-  XFree (xcoords);
-
-  /* free the events we allocated too much */
-  for (i = j; i < tmp_n_events; i++)
-    {
-      g_free (coords[i]);
-      coords[i] = NULL;
-    }
-
-  tmp_n_events = j;
-
-  if (tmp_n_events == 0)
-    {
-      gdk_device_free_history (coords, tmp_n_events);
-      return FALSE;
-    }
-
-  if (n_events)
-    *n_events = tmp_n_events;
-
-  if (events)
-    *events = coords;
-  else if (coords)
-    gdk_device_free_history (coords, tmp_n_events);
-
-  return TRUE;
-}
-
-static void
-gdk_device_core_get_state (GdkDevice       *device,
-                           GdkWindow       *window,
-                           gdouble         *axes,
-                           GdkModifierType *mask)
-{
-  gint x_int, y_int;
-
-  gdk_window_get_pointer (window, &x_int, &y_int, mask);
-
-  if (axes)
-    {
-      axes[0] = x_int;
-      axes[1] = y_int;
-    }
-}
-
-static void
-gdk_device_core_set_window_cursor (GdkDevice *device,
-                                   GdkWindow *window,
-                                   GdkCursor *cursor)
-{
-  Cursor xcursor;
-
-  if (!cursor)
-    xcursor = None;
-  else
-    xcursor = gdk_x11_cursor_get_xcursor (cursor);
-
-  XDefineCursor (GDK_WINDOW_XDISPLAY (window),
-                 GDK_WINDOW_XID (window),
-                 xcursor);
-}
-
-static void
-gdk_device_core_warp (GdkDevice *device,
-                      GdkScreen *screen,
-                      gint       x,
-                      gint       y)
-{
-  Display *xdisplay;
-  Window dest;
-
-  xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
-  dest = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
-
-  XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
-}
-
-static gboolean
-gdk_device_core_query_state (GdkDevice        *device,
-                             GdkWindow        *window,
-                             GdkWindow       **root_window,
-                             GdkWindow       **child_window,
-                             gint             *root_x,
-                             gint             *root_y,
-                             gint             *win_x,
-                             gint             *win_y,
-                             GdkModifierType  *mask)
-{
-  GdkDisplay *display;
-  GdkScreen *default_screen;
-  Window xroot_window, xchild_window;
-  int xroot_x, xroot_y, xwin_x, xwin_y;
-  unsigned int xmask;
-
-  display = gdk_window_get_display (window);
-  default_screen = gdk_display_get_default_screen (display);
-
-  if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
-    {
-      if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window),
-                          GDK_WINDOW_XID (window),
-                          &xroot_window,
-                          &xchild_window,
-                          &xroot_x,
-                          &xroot_y,
-                          &xwin_x,
-                          &xwin_y,
-                          &xmask))
-        return FALSE;
-    }
-  else
-    {
-      XSetWindowAttributes attributes;
-      Display *xdisplay;
-      Window xwindow, w;
-
-      /* FIXME: untrusted clients not multidevice-safe */
-      xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
-      xwindow = GDK_SCREEN_XROOTWIN (default_screen);
-
-      w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
-                         CopyFromParent, InputOnly, CopyFromParent,
-                         0, &attributes);
-      XQueryPointer (xdisplay, w,
-                     &xroot_window,
-                     &xchild_window,
-                     &xroot_x,
-                     &xroot_y,
-                     &xwin_x,
-                     &xwin_y,
-                     &xmask);
-      XDestroyWindow (xdisplay, w);
-    }
-
-  if (root_window)
-    *root_window = gdk_x11_window_lookup_for_display (display, xroot_window);
-
-  if (child_window)
-    *child_window = gdk_x11_window_lookup_for_display (display, xchild_window);
-
-  if (root_x)
-    *root_x = xroot_x;
-
-  if (root_y)
-    *root_y = xroot_y;
-
-  if (win_x)
-    *win_x = xwin_x;
-
-  if (win_y)
-    *win_y = xwin_y;
-
-  if (mask)
-    *mask = xmask;
-
-  return TRUE;
-}
-
-static GdkGrabStatus
-gdk_device_core_grab (GdkDevice    *device,
-                      GdkWindow    *window,
-                      gboolean      owner_events,
-                      GdkEventMask  event_mask,
-                      GdkWindow    *confine_to,
-                      GdkCursor    *cursor,
-                      guint32       time_)
-{
-  GdkDisplay *display;
-  Window xwindow, xconfine_to;
-  gint status;
-
-  display = gdk_device_get_display (device);
-
-  xwindow = GDK_WINDOW_XID (window);
-
-  if (confine_to)
-    confine_to = _gdk_window_get_impl_window (confine_to);
-
-  if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
-    xconfine_to = None;
-  else
-    xconfine_to = GDK_WINDOW_XID (confine_to);
-
-#ifdef G_ENABLE_DEBUG
-  if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
-    status = GrabSuccess;
-  else
-#endif
-  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
-    {
-      /* Device is a keyboard */
-      status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display),
-                              xwindow,
-                              owner_events,
-                              GrabModeAsync, GrabModeAsync,
-                              time_);
-    }
-  else
-    {
-      Cursor xcursor;
-      guint xevent_mask;
-      gint i;
-
-      /* Device is a pointer */
-      if (!cursor)
-        xcursor = None;
-      else
-        {
-          _gdk_x11_cursor_update_theme (cursor);
-          xcursor = gdk_x11_cursor_get_xcursor (cursor);
-        }
-
-      xevent_mask = 0;
-
-      for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
-        {
-          if (event_mask & (1 << (i + 1)))
-            xevent_mask |= _gdk_x11_event_mask_table[i];
-        }
-
-      /* We don't want to set a native motion hint mask, as we're emulating motion
-       * hints. If we set a native one we just wouldn't get any events.
-       */
-      xevent_mask &= ~PointerMotionHintMask;
-
-      status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display),
-                             xwindow,
-                             owner_events,
-                             xevent_mask,
-                             GrabModeAsync, GrabModeAsync,
-                             xconfine_to,
-                             xcursor,
-                             time_);
-    }
-
-  _gdk_x11_display_update_grab_info (display, device, status);
-
-  return _gdk_x11_convert_grab_status (status);
-}
-
-static void
-gdk_device_core_ungrab (GdkDevice *device,
-                        guint32    time_)
-{
-  GdkDisplay *display;
-  gulong serial;
-
-  display = gdk_device_get_display (device);
-  serial = NextRequest (GDK_DISPLAY_XDISPLAY (display));
-
-  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
-    XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
-  else
-    XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
-
-  _gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
-}
-
-static GdkWindow *
-gdk_device_core_window_at_position (GdkDevice       *device,
-                                    gint            *win_x,
-                                    gint            *win_y,
-                                    GdkModifierType *mask,
-                                    gboolean         get_toplevel)
-{
-  GdkDisplay *display;
-  GdkScreen *screen;
-  Display *xdisplay;
-  GdkWindow *window;
-  Window xwindow, root, child, last;
-  int xroot_x, xroot_y, xwin_x, xwin_y;
-  unsigned int xmask;
-
-  last = None;
-  display = gdk_device_get_display (device);
-  screen = gdk_display_get_default_screen (display);
-
-  /* This function really only works if the mouse pointer is held still
-   * during its operation. If it moves from one leaf window to another
-   * than we'll end up with inaccurate values for win_x, win_y
-   * and the result.
-   */
-  gdk_x11_display_grab (display);
-
-  xdisplay = GDK_SCREEN_XDISPLAY (screen);
-  xwindow = GDK_SCREEN_XROOTWIN (screen);
-
-  if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
-    {
-      XQueryPointer (xdisplay, xwindow,
-                     &root, &child,
-                     &xroot_x, &xroot_y,
-                     &xwin_x, &xwin_y,
-                     &xmask);
-
-      if (root == xwindow)
-        xwindow = child;
-      else
-       xwindow = root;
-    }
-  else
-    {
-      gint i, screens, width, height;
-      GList *toplevels, *list;
-      Window pointer_window, root, child;
-      int rootx = -1, rooty = -1;
-      int winx, winy;
-      unsigned int xmask;
-
-      /* FIXME: untrusted clients case not multidevice-safe */
-      pointer_window = None;
-      screens = gdk_display_get_n_screens (display);
-
-      for (i = 0; i < screens; ++i)
-        {
-          screen = gdk_display_get_screen (display, i);
-          toplevels = gdk_screen_get_toplevel_windows (screen);
-          for (list = toplevels; list != NULL; list = g_list_next (list))
-            {
-              window = GDK_WINDOW (list->data);
-              xwindow = GDK_WINDOW_XID (window);
-              gdk_x11_display_error_trap_push (display);
-              XQueryPointer (xdisplay, xwindow,
-                             &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
-              if (gdk_x11_display_error_trap_pop (display))
-                continue;
-              if (child != None)
-                {
-                  pointer_window = child;
-                  break;
-                }
-              gdk_window_get_geometry (window, NULL, NULL, &width, &height);
-              if (winx >= 0 && winy >= 0 && winx < width && winy < height)
-                {
-                  /* A childless toplevel, or below another window? */
-                  XSetWindowAttributes attributes;
-                  Window w;
-
-                  w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
-                                     CopyFromParent, InputOnly, CopyFromParent,
-                                     0, &attributes);
-                  XMapWindow (xdisplay, w);
-                  XQueryPointer (xdisplay, xwindow,
-                                 &root, &child,
-                                 &rootx, &rooty, &winx, &winy, &xmask);
-                  XDestroyWindow (xdisplay, w);
-                  if (child == w)
-                    {
-                      pointer_window = xwindow;
-                      break;
-                    }
-                }
-            }
-
-          g_list_free (toplevels);
-          if (pointer_window != None)
-            break;
-        }
-
-      xwindow = pointer_window;
-    }
-
-  while (xwindow)
-    {
-      last = xwindow;
-      gdk_x11_display_error_trap_push (display);
-      XQueryPointer (xdisplay, xwindow,
-                     &root, &xwindow,
-                     &xroot_x, &xroot_y,
-                     &xwin_x, &xwin_y,
-                     &xmask);
-      if (gdk_x11_display_error_trap_pop (display))
-        break;
-
-      if (get_toplevel && last != root &&
-          (window = gdk_x11_window_lookup_for_display (display, last)) != NULL &&
-          window->window_type != GDK_WINDOW_FOREIGN)
-        {
-          xwindow = last;
-          break;
-        }
-    }
-
-  gdk_x11_display_ungrab (display);
-
-  window = gdk_x11_window_lookup_for_display (display, last);
-
-  if (win_x)
-    *win_x = (window) ? xwin_x : -1;
-
-  if (win_y)
-    *win_y = (window) ? xwin_y : -1;
-
-  if (mask)
-    *mask = xmask;
-
-  return window;
-}
-
-static void
-gdk_device_core_select_window_events (GdkDevice    *device,
-                                      GdkWindow    *window,
-                                      GdkEventMask  event_mask)
-{
-  GdkEventMask filter_mask, window_mask;
-  guint xmask = 0;
-  gint i;
-
-  window_mask = gdk_window_get_events (window);
-  filter_mask = (GDK_POINTER_MOTION_MASK &
-                 GDK_POINTER_MOTION_HINT_MASK &
-                 GDK_BUTTON_MOTION_MASK &
-                 GDK_BUTTON1_MOTION_MASK &
-                 GDK_BUTTON2_MOTION_MASK &
-                 GDK_BUTTON3_MOTION_MASK &
-                 GDK_BUTTON_PRESS_MASK &
-                 GDK_BUTTON_RELEASE_MASK &
-                 GDK_KEY_PRESS_MASK &
-                 GDK_KEY_RELEASE_MASK &
-                 GDK_ENTER_NOTIFY_MASK &
-                 GDK_LEAVE_NOTIFY_MASK &
-                 GDK_FOCUS_CHANGE_MASK &
-                 GDK_PROXIMITY_IN_MASK &
-                 GDK_PROXIMITY_OUT_MASK &
-                 GDK_SCROLL_MASK);
-
-  /* Filter out non-device events */
-  event_mask &= filter_mask;
-
-  /* Unset device events on window mask */
-  window_mask &= ~(filter_mask);
-
-  /* Combine masks */
-  event_mask |= window_mask;
-
-  for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
-    {
-      if (event_mask & (1 << (i + 1)))
-        xmask |= _gdk_x11_event_mask_table[i];
-    }
-
-  if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
-    xmask |= StructureNotifyMask | PropertyChangeMask;
-
-  XSelectInput (GDK_WINDOW_XDISPLAY (window),
-                GDK_WINDOW_XID (window),
-                xmask);
-}
diff --git a/gdk/x11/gdkdevice-core.h b/gdk/x11/gdkdevice-core.h
deleted file mode 100644 (file)
index af425da..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GDK_DEVICE_CORE_H__
-#define __GDK_DEVICE_CORE_H__
-
-#include "gdkdeviceprivate.h"
-
-G_BEGIN_DECLS
-
-#define GDK_TYPE_DEVICE_CORE         (gdk_device_core_get_type ())
-#define GDK_DEVICE_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
-#define GDK_DEVICE_CORE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
-#define GDK_IS_DEVICE_CORE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE))
-#define GDK_IS_DEVICE_CORE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE))
-#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
-
-typedef struct _GdkDeviceCore GdkDeviceCore;
-typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass;
-
-struct _GdkDeviceCore
-{
-  GdkDevice parent_instance;
-};
-
-struct _GdkDeviceCoreClass
-{
-  GdkDeviceClass parent_class;
-};
-
-G_GNUC_INTERNAL
-GType gdk_device_core_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* __GDK_DEVICE_CORE_H__ */
diff --git a/gdk/x11/gdkdevicemanager-core-x11.c b/gdk/x11/gdkdevicemanager-core-x11.c
new file mode 100644 (file)
index 0000000..99c0b07
--- /dev/null
@@ -0,0 +1,909 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkx11devicemanager-core.h"
+#include "gdkx11device-core.h"
+
+#include "gdkkeysyms.h"
+#include "gdkdevicemanagerprivate.h"
+#include "gdkdisplayprivate.h"
+#include "gdkeventtranslator.h"
+#include "gdkprivate-x11.h"
+
+#ifdef HAVE_XKB
+#include <X11/XKBlib.h>
+#endif
+
+
+#define HAS_FOCUS(toplevel)                           \
+  ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+static void    gdk_x11_device_manager_core_finalize    (GObject *object);
+static void    gdk_x11_device_manager_core_constructed (GObject *object);
+
+static GList * gdk_x11_device_manager_core_list_devices (GdkDeviceManager *device_manager,
+                                                         GdkDeviceType     type);
+static GdkDevice * gdk_x11_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager);
+
+static void     gdk_x11_device_manager_event_translator_init (GdkEventTranslatorIface *iface);
+
+static gboolean gdk_x11_device_manager_core_translate_event  (GdkEventTranslator *translator,
+                                                              GdkDisplay         *display,
+                                                              GdkEvent           *event,
+                                                              XEvent             *xevent);
+
+
+G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerCore, gdk_x11_device_manager_core, GDK_TYPE_DEVICE_MANAGER,
+                         G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
+                                                gdk_x11_device_manager_event_translator_init))
+
+static void
+gdk_x11_device_manager_core_class_init (GdkX11DeviceManagerCoreClass *klass)
+{
+  GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gdk_x11_device_manager_core_finalize;
+  object_class->constructed = gdk_x11_device_manager_core_constructed;
+  device_manager_class->list_devices = gdk_x11_device_manager_core_list_devices;
+  device_manager_class->get_client_pointer = gdk_x11_device_manager_core_get_client_pointer;
+}
+
+static void
+gdk_x11_device_manager_event_translator_init (GdkEventTranslatorIface *iface)
+{
+  iface->translate_event = gdk_x11_device_manager_core_translate_event;
+}
+
+static GdkDevice *
+create_core_pointer (GdkDeviceManager *device_manager,
+                     GdkDisplay       *display)
+{
+  return g_object_new (GDK_TYPE_X11_DEVICE_CORE,
+                       "name", "Core Pointer",
+                       "type", GDK_DEVICE_TYPE_MASTER,
+                       "input-source", GDK_SOURCE_MOUSE,
+                       "input-mode", GDK_MODE_SCREEN,
+                       "has-cursor", TRUE,
+                       "display", display,
+                       "device-manager", device_manager,
+                       NULL);
+}
+
+static GdkDevice *
+create_core_keyboard (GdkDeviceManager *device_manager,
+                      GdkDisplay       *display)
+{
+  return g_object_new (GDK_TYPE_X11_DEVICE_CORE,
+                       "name", "Core Keyboard",
+                       "type", GDK_DEVICE_TYPE_MASTER,
+                       "input-source", GDK_SOURCE_KEYBOARD,
+                       "input-mode", GDK_MODE_SCREEN,
+                       "has-cursor", FALSE,
+                       "display", display,
+                       "device-manager", device_manager,
+                       NULL);
+}
+
+static void
+gdk_x11_device_manager_core_init (GdkX11DeviceManagerCore *device_manager)
+{
+}
+
+static void
+gdk_x11_device_manager_core_finalize (GObject *object)
+{
+  GdkX11DeviceManagerCore *device_manager_core;
+
+  device_manager_core = GDK_X11_DEVICE_MANAGER_CORE (object);
+
+  g_object_unref (device_manager_core->core_pointer);
+  g_object_unref (device_manager_core->core_keyboard);
+
+  G_OBJECT_CLASS (gdk_x11_device_manager_core_parent_class)->finalize (object);
+}
+
+static void
+gdk_x11_device_manager_core_constructed (GObject *object)
+{
+  GdkX11DeviceManagerCore *device_manager;
+  GdkDisplay *display;
+
+  device_manager = GDK_X11_DEVICE_MANAGER_CORE (object);
+  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
+  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
+  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
+
+  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
+  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
+}
+
+static void
+translate_key_event (GdkDisplay              *display,
+                     GdkX11DeviceManagerCore *device_manager,
+                     GdkEvent                *event,
+                     XEvent                  *xevent)
+{
+  GdkKeymap *keymap = gdk_keymap_get_for_display (display);
+  GdkModifierType consumed, state;
+  gunichar c = 0;
+  gchar buf[7];
+
+  event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
+  event->key.time = xevent->xkey.time;
+  gdk_event_set_device (event, device_manager->core_keyboard);
+
+  event->key.state = (GdkModifierType) xevent->xkey.state;
+  event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
+  event->key.hardware_keycode = xevent->xkey.keycode;
+
+  event->key.keyval = GDK_KEY_VoidSymbol;
+
+  gdk_keymap_translate_keyboard_state (keymap,
+                                       event->key.hardware_keycode,
+                                       event->key.state,
+                                       event->key.group,
+                                       &event->key.keyval,
+                                       NULL, NULL, &consumed);
+
+  state = event->key.state & ~consumed;
+  _gdk_x11_keymap_add_virt_mods (keymap, &state);
+  event->key.state |= state;
+
+  event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
+
+  /* Fill in event->string crudely, since various programs
+   * depend on it.
+   */
+  event->key.string = NULL;
+
+  if (event->key.keyval != GDK_KEY_VoidSymbol)
+    c = gdk_keyval_to_unicode (event->key.keyval);
+
+  if (c)
+    {
+      gsize bytes_written;
+      gint len;
+
+      /* Apply the control key - Taken from Xlib
+       */
+      if (event->key.state & GDK_CONTROL_MASK)
+        {
+          if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
+          else if (c == '2')
+            {
+              event->key.string = g_memdup ("\0\0", 2);
+              event->key.length = 1;
+              buf[0] = '\0';
+              goto out;
+            }
+          else if (c >= '3' && c <= '7') c -= ('3' - '\033');
+          else if (c == '8') c = '\177';
+          else if (c == '/') c = '_' & 0x1F;
+        }
+
+      len = g_unichar_to_utf8 (c, buf);
+      buf[len] = '\0';
+
+      event->key.string = g_locale_from_utf8 (buf, len,
+                                              NULL, &bytes_written,
+                                              NULL);
+      if (event->key.string)
+        event->key.length = bytes_written;
+    }
+  else if (event->key.keyval == GDK_KEY_Escape)
+    {
+      event->key.length = 1;
+      event->key.string = g_strdup ("\033");
+    }
+  else if (event->key.keyval == GDK_KEY_Return ||
+          event->key.keyval == GDK_KEY_KP_Enter)
+    {
+      event->key.length = 1;
+      event->key.string = g_strdup ("\r");
+    }
+
+  if (!event->key.string)
+    {
+      event->key.length = 0;
+      event->key.string = g_strdup ("");
+    }
+
+ out:
+#ifdef G_ENABLE_DEBUG
+  if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
+    {
+      g_message ("%s:\t\twindow: %ld     key: %12s  %d",
+                 event->type == GDK_KEY_PRESS ? "key press  " : "key release",
+                 xevent->xkey.window,
+                 event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
+                 event->key.keyval);
+
+      if (event->key.length > 0)
+        g_message ("\t\tlength: %4d string: \"%s\"",
+                   event->key.length, buf);
+    }
+#endif /* G_ENABLE_DEBUG */
+  return;
+}
+
+#ifdef G_ENABLE_DEBUG
+static const char notify_modes[][19] = {
+  "NotifyNormal",
+  "NotifyGrab",
+  "NotifyUngrab",
+  "NotifyWhileGrabbed"
+};
+
+static const char notify_details[][23] = {
+  "NotifyAncestor",
+  "NotifyVirtual",
+  "NotifyInferior",
+  "NotifyNonlinear",
+  "NotifyNonlinearVirtual",
+  "NotifyPointer",
+  "NotifyPointerRoot",
+  "NotifyDetailNone"
+};
+#endif
+
+static void
+set_user_time (GdkWindow *window,
+               GdkEvent  *event)
+{
+  g_return_if_fail (event != NULL);
+
+  window = gdk_window_get_toplevel (event->client.window);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  /* If an event doesn't have a valid timestamp, we shouldn't use it
+   * to update the latest user interaction time.
+   */
+  if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
+    gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+                                  gdk_event_get_time (event));
+}
+
+static void
+generate_focus_event (GdkX11DeviceManagerCore *device_manager,
+                      GdkWindow               *window,
+                      gboolean                 in)
+{
+  GdkEvent *event;
+
+  event = gdk_event_new (GDK_FOCUS_CHANGE);
+  event->focus_change.window = g_object_ref (window);
+  event->focus_change.send_event = FALSE;
+  event->focus_change.in = in;
+  gdk_event_set_device (event, device_manager->core_keyboard);
+
+  gdk_event_put (event);
+  gdk_event_free (event);
+}
+
+static gboolean
+set_screen_from_root (GdkDisplay *display,
+                      GdkEvent   *event,
+                      Window      xrootwin)
+{
+  GdkScreen *screen;
+
+  screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
+
+  if (screen)
+    {
+      gdk_event_set_screen (event, screen);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static GdkCrossingMode
+translate_crossing_mode (int mode)
+{
+  switch (mode)
+    {
+    case NotifyNormal:
+      return GDK_CROSSING_NORMAL;
+    case NotifyGrab:
+      return GDK_CROSSING_GRAB;
+    case NotifyUngrab:
+      return GDK_CROSSING_UNGRAB;
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static GdkNotifyType
+translate_notify_type (int detail)
+{
+  switch (detail)
+    {
+    case NotifyInferior:
+      return GDK_NOTIFY_INFERIOR;
+    case NotifyAncestor:
+      return GDK_NOTIFY_ANCESTOR;
+    case NotifyVirtual:
+      return GDK_NOTIFY_VIRTUAL;
+    case NotifyNonlinear:
+      return GDK_NOTIFY_NONLINEAR;
+    case NotifyNonlinearVirtual:
+      return GDK_NOTIFY_NONLINEAR_VIRTUAL;
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static gboolean
+is_parent_of (GdkWindow *parent,
+              GdkWindow *child)
+{
+  GdkWindow *w;
+
+  w = child;
+  while (w != NULL)
+    {
+      if (w == parent)
+        return TRUE;
+
+      w = gdk_window_get_parent (w);
+    }
+
+  return FALSE;
+}
+
+static GdkWindow *
+get_event_window (GdkEventTranslator *translator,
+                  XEvent             *xevent)
+{
+  GdkDeviceManager *device_manager;
+  GdkDisplay *display;
+  GdkWindow *window;
+
+  device_manager = GDK_DEVICE_MANAGER (translator);
+  display = gdk_device_manager_get_display (device_manager);
+  window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
+
+  /* Apply keyboard grabs to non-native windows */
+  if (xevent->type == KeyPress || xevent->type == KeyRelease)
+    {
+      GdkDeviceGrabInfo *info;
+      gulong serial;
+
+      serial = _gdk_display_get_next_serial (display);
+      info = _gdk_display_has_device_grab (display,
+                                           GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
+                                           serial);
+      if (info &&
+          (!is_parent_of (info->window, window) ||
+           !info->owner_events))
+        {
+          /* Report key event against grab window */
+          window = info->window;
+        }
+    }
+
+  return window;
+}
+
+static gboolean
+gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
+                                             GdkDisplay         *display,
+                                             GdkEvent           *event,
+                                             XEvent             *xevent)
+{
+  GdkX11DeviceManagerCore *device_manager;
+  GdkWindow *window;
+  GdkWindowImplX11 *window_impl = NULL;
+  gboolean return_val;
+  GdkToplevelX11 *toplevel = NULL;
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+
+  device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator);
+  return_val = FALSE;
+
+  window = get_event_window (translator, xevent);
+
+  if (window)
+    {
+      if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
+        return FALSE;
+
+      toplevel = _gdk_x11_window_get_toplevel (window);
+      window_impl = GDK_WINDOW_IMPL_X11 (window->impl);
+      g_object_ref (window);
+    }
+
+  event->any.window = window;
+  event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
+
+  if (window && GDK_WINDOW_DESTROYED (window))
+    {
+      if (xevent->type != DestroyNotify)
+        {
+          return_val = FALSE;
+          goto done;
+        }
+    }
+
+  if (window &&
+      (xevent->type == MotionNotify ||
+       xevent->type == ButtonRelease))
+    {
+      if (_gdk_x11_moveresize_handle_event (xevent))
+        {
+          return_val = FALSE;
+          goto done;
+        }
+    }
+
+  /* We do a "manual" conversion of the XEvent to a
+   *  GdkEvent. The structures are mostly the same so
+   *  the conversion is fairly straightforward. We also
+   *  optionally print debugging info regarding events
+   *  received.
+   */
+
+  return_val = TRUE;
+
+  switch (xevent->type)
+    {
+    case KeyPress:
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+      translate_key_event (display, device_manager, event, xevent);
+      set_user_time (window, event);
+      break;
+
+    case KeyRelease:
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      /* Emulate detectable auto-repeat by checking to see
+       * if the next event is a key press with the same
+       * keycode and timestamp, and if so, ignoring the event.
+       */
+
+      if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
+        {
+          XEvent next_event;
+
+          XPeekEvent (xevent->xkey.display, &next_event);
+
+          if (next_event.type == KeyPress &&
+              next_event.xkey.keycode == xevent->xkey.keycode &&
+              next_event.xkey.time == xevent->xkey.time)
+            {
+              return_val = FALSE;
+              break;
+            }
+        }
+
+      translate_key_event (display, device_manager, event, xevent);
+      break;
+
+    case ButtonPress:
+      GDK_NOTE (EVENTS,
+                g_message ("button press:\t\twindow: %ld  x,y: %d %d  button: %d",
+                           xevent->xbutton.window,
+                           xevent->xbutton.x, xevent->xbutton.y,
+                           xevent->xbutton.button));
+
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      /* If we get a ButtonPress event where the button is 4 or 5,
+         it's a Scroll event */
+      switch (xevent->xbutton.button)
+        {
+        case 4: /* up */
+        case 5: /* down */
+        case 6: /* left */
+        case 7: /* right */
+          event->scroll.type = GDK_SCROLL;
+
+          if (xevent->xbutton.button == 4)
+            event->scroll.direction = GDK_SCROLL_UP;
+          else if (xevent->xbutton.button == 5)
+            event->scroll.direction = GDK_SCROLL_DOWN;
+          else if (xevent->xbutton.button == 6)
+            event->scroll.direction = GDK_SCROLL_LEFT;
+          else
+            event->scroll.direction = GDK_SCROLL_RIGHT;
+
+          event->scroll.window = window;
+          event->scroll.time = xevent->xbutton.time;
+          event->scroll.x = (gdouble) xevent->xbutton.x;
+          event->scroll.y = (gdouble) xevent->xbutton.y;
+          event->scroll.x_root = (gdouble) xevent->xbutton.x_root;
+          event->scroll.y_root = (gdouble) xevent->xbutton.y_root;
+          event->scroll.state = (GdkModifierType) xevent->xbutton.state;
+          event->scroll.device = device_manager->core_pointer;
+
+          if (!set_screen_from_root (display, event, xevent->xbutton.root))
+            {
+              return_val = FALSE;
+              break;
+            }
+
+          break;
+
+        default:
+          event->button.type = GDK_BUTTON_PRESS;
+          event->button.window = window;
+          event->button.time = xevent->xbutton.time;
+          event->button.x = (gdouble) xevent->xbutton.x;
+          event->button.y = (gdouble) xevent->xbutton.y;
+          event->button.x_root = (gdouble) xevent->xbutton.x_root;
+          event->button.y_root = (gdouble) xevent->xbutton.y_root;
+          event->button.axes = NULL;
+          event->button.state = (GdkModifierType) xevent->xbutton.state;
+          event->button.button = xevent->xbutton.button;
+          event->button.device = device_manager->core_pointer;
+
+          if (!set_screen_from_root (display, event, xevent->xbutton.root))
+            return_val = FALSE;
+
+          break;
+        }
+
+      set_user_time (window, event);
+
+      break;
+
+    case ButtonRelease:
+      GDK_NOTE (EVENTS,
+                g_message ("button release:\twindow: %ld  x,y: %d %d  button: %d",
+                           xevent->xbutton.window,
+                           xevent->xbutton.x, xevent->xbutton.y,
+                           xevent->xbutton.button));
+
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      /* We treat button presses as scroll wheel events, so ignore the release */
+      if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
+          xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      event->button.type = GDK_BUTTON_RELEASE;
+      event->button.window = window;
+      event->button.time = xevent->xbutton.time;
+      event->button.x = (gdouble) xevent->xbutton.x;
+      event->button.y = (gdouble) xevent->xbutton.y;
+      event->button.x_root = (gdouble) xevent->xbutton.x_root;
+      event->button.y_root = (gdouble) xevent->xbutton.y_root;
+      event->button.axes = NULL;
+      event->button.state = (GdkModifierType) xevent->xbutton.state;
+      event->button.button = xevent->xbutton.button;
+      event->button.device = device_manager->core_pointer;
+
+      if (!set_screen_from_root (display, event, xevent->xbutton.root))
+        return_val = FALSE;
+
+      break;
+
+    case MotionNotify:
+      GDK_NOTE (EVENTS,
+                g_message ("motion notify:\t\twindow: %ld  x,y: %d %d  hint: %s",
+                           xevent->xmotion.window,
+                           xevent->xmotion.x, xevent->xmotion.y,
+                           (xevent->xmotion.is_hint) ? "true" : "false"));
+
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = window;
+      event->motion.time = xevent->xmotion.time;
+      event->motion.x = (gdouble) xevent->xmotion.x;
+      event->motion.y = (gdouble) xevent->xmotion.y;
+      event->motion.x_root = (gdouble) xevent->xmotion.x_root;
+      event->motion.y_root = (gdouble) xevent->xmotion.y_root;
+      event->motion.axes = NULL;
+      event->motion.state = (GdkModifierType) xevent->xmotion.state;
+      event->motion.is_hint = xevent->xmotion.is_hint;
+      event->motion.device = device_manager->core_pointer;
+
+      if (!set_screen_from_root (display, event, xevent->xbutton.root))
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      break;
+
+    case EnterNotify:
+      GDK_NOTE (EVENTS,
+                g_message ("enter notify:\t\twindow: %ld  detail: %d subwin: %ld",
+                           xevent->xcrossing.window,
+                           xevent->xcrossing.detail,
+                           xevent->xcrossing.subwindow));
+
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      if (!set_screen_from_root (display, event, xevent->xbutton.root))
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      event->crossing.type = GDK_ENTER_NOTIFY;
+      event->crossing.window = window;
+      gdk_event_set_device (event, device_manager->core_pointer);
+
+      /* If the subwindow field of the XEvent is non-NULL, then
+       *  lookup the corresponding GdkWindow.
+       */
+      if (xevent->xcrossing.subwindow != None)
+        event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
+      else
+        event->crossing.subwindow = NULL;
+
+      event->crossing.time = xevent->xcrossing.time;
+      event->crossing.x = (gdouble) xevent->xcrossing.x;
+      event->crossing.y = (gdouble) xevent->xcrossing.y;
+      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
+      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
+
+      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
+      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
+
+      event->crossing.focus = xevent->xcrossing.focus;
+      event->crossing.state = xevent->xcrossing.state;
+
+      break;
+
+    case LeaveNotify:
+      GDK_NOTE (EVENTS,
+                g_message ("leave notify:\t\twindow: %ld  detail: %d subwin: %ld",
+                           xevent->xcrossing.window,
+                           xevent->xcrossing.detail, xevent->xcrossing.subwindow));
+
+      if (window == NULL)
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      if (!set_screen_from_root (display, event, xevent->xbutton.root))
+        {
+          return_val = FALSE;
+          break;
+        }
+
+      event->crossing.type = GDK_LEAVE_NOTIFY;
+      event->crossing.window = window;
+      gdk_event_set_device (event, device_manager->core_pointer);
+
+      /* If the subwindow field of the XEvent is non-NULL, then
+       *  lookup the corresponding GdkWindow.
+       */
+      if (xevent->xcrossing.subwindow != None)
+        event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
+      else
+        event->crossing.subwindow = NULL;
+
+      event->crossing.time = xevent->xcrossing.time;
+      event->crossing.x = (gdouble) xevent->xcrossing.x;
+      event->crossing.y = (gdouble) xevent->xcrossing.y;
+      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
+      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
+
+      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
+      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
+
+      event->crossing.focus = xevent->xcrossing.focus;
+      event->crossing.state = xevent->xcrossing.state;
+
+      break;
+
+      /* We only care about focus events that indicate that _this_
+       * window (not a ancestor or child) got or lost the focus
+       */
+    case FocusIn:
+      GDK_NOTE (EVENTS,
+                g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
+                           xevent->xfocus.window,
+                           notify_details[xevent->xfocus.detail],
+                           notify_modes[xevent->xfocus.mode]));
+
+      if (toplevel)
+        {
+          gboolean had_focus = HAS_FOCUS (toplevel);
+
+          switch (xevent->xfocus.detail)
+            {
+            case NotifyAncestor:
+            case NotifyVirtual:
+              /* When the focus moves from an ancestor of the window to
+               * the window or a descendent of the window, *and* the
+               * pointer is inside the window, then we were previously
+               * receiving keystroke events in the has_pointer_focus
+               * case and are now receiving them in the
+               * has_focus_window case.
+               */
+              if (toplevel->has_pointer &&
+                  xevent->xfocus.mode != NotifyGrab &&
+                  xevent->xfocus.mode != NotifyUngrab)
+                toplevel->has_pointer_focus = FALSE;
+
+              /* fall through */
+            case NotifyNonlinear:
+            case NotifyNonlinearVirtual:
+              if (xevent->xfocus.mode != NotifyGrab &&
+                  xevent->xfocus.mode != NotifyUngrab)
+                toplevel->has_focus_window = TRUE;
+              /* We pretend that the focus moves to the grab
+               * window, so we pay attention to NotifyGrab
+               * NotifyUngrab, and ignore NotifyWhileGrabbed
+               */
+              if (xevent->xfocus.mode != NotifyWhileGrabbed)
+                toplevel->has_focus = TRUE;
+              break;
+            case NotifyPointer:
+              /* The X server sends NotifyPointer/NotifyGrab,
+               * but the pointer focus is ignored while a
+               * grab is in effect
+               */
+              if (xevent->xfocus.mode != NotifyGrab &&
+                  xevent->xfocus.mode != NotifyUngrab)
+                toplevel->has_pointer_focus = TRUE;
+              break;
+            case NotifyInferior:
+            case NotifyPointerRoot:
+            case NotifyDetailNone:
+              break;
+            }
+
+          if (HAS_FOCUS (toplevel) != had_focus)
+            generate_focus_event (device_manager, window, TRUE);
+        }
+      break;
+    case FocusOut:
+      GDK_NOTE (EVENTS,
+                g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
+                           xevent->xfocus.window,
+                           notify_details[xevent->xfocus.detail],
+                           notify_modes[xevent->xfocus.mode]));
+
+      if (toplevel)
+        {
+          gboolean had_focus = HAS_FOCUS (toplevel);
+
+          switch (xevent->xfocus.detail)
+            {
+            case NotifyAncestor:
+            case NotifyVirtual:
+              /* When the focus moves from the window or a descendent
+               * of the window to an ancestor of the window, *and* the
+               * pointer is inside the window, then we were previously
+               * receiving keystroke events in the has_focus_window
+               * case and are now receiving them in the
+               * has_pointer_focus case.
+               */
+              if (toplevel->has_pointer &&
+                  xevent->xfocus.mode != NotifyGrab &&
+                  xevent->xfocus.mode != NotifyUngrab)
+                toplevel->has_pointer_focus = TRUE;
+
+              /* fall through */
+            case NotifyNonlinear:
+            case NotifyNonlinearVirtual:
+              if (xevent->xfocus.mode != NotifyGrab &&
+                  xevent->xfocus.mode != NotifyUngrab)
+                toplevel->has_focus_window = FALSE;
+              if (xevent->xfocus.mode != NotifyWhileGrabbed)
+                toplevel->has_focus = FALSE;
+              break;
+            case NotifyPointer:
+              if (xevent->xfocus.mode != NotifyGrab &&
+                  xevent->xfocus.mode != NotifyUngrab)
+                toplevel->has_pointer_focus = FALSE;
+            break;
+            case NotifyInferior:
+            case NotifyPointerRoot:
+            case NotifyDetailNone:
+              break;
+            }
+
+          if (HAS_FOCUS (toplevel) != had_focus)
+            generate_focus_event (device_manager, window, FALSE);
+        }
+      break;
+
+    default:
+        return_val = FALSE;
+    }
+
+ done:
+  if (return_val)
+    {
+      if (event->any.window)
+        g_object_ref (event->any.window);
+
+      if (((event->any.type == GDK_ENTER_NOTIFY) ||
+           (event->any.type == GDK_LEAVE_NOTIFY)) &&
+          (event->crossing.subwindow != NULL))
+        g_object_ref (event->crossing.subwindow);
+    }
+  else
+    {
+      /* Mark this event as having no resources to be freed */
+      event->any.window = NULL;
+      event->any.type = GDK_NOTHING;
+    }
+
+  if (window)
+    g_object_unref (window);
+
+  return return_val;
+}
+
+static GList *
+gdk_x11_device_manager_core_list_devices (GdkDeviceManager *device_manager,
+                                          GdkDeviceType     type)
+{
+  GdkX11DeviceManagerCore *device_manager_core;
+  GList *devices = NULL;
+
+  if (type == GDK_DEVICE_TYPE_MASTER)
+    {
+      device_manager_core = (GdkX11DeviceManagerCore *) device_manager;
+      devices = g_list_prepend (devices, device_manager_core->core_keyboard);
+      devices = g_list_prepend (devices, device_manager_core->core_pointer);
+    }
+
+  return devices;
+}
+
+static GdkDevice *
+gdk_x11_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager)
+{
+  GdkX11DeviceManagerCore *device_manager_core;
+
+  device_manager_core = (GdkX11DeviceManagerCore *) device_manager;
+  return device_manager_core->core_pointer;
+}
diff --git a/gdk/x11/gdkdevicemanager-core.c b/gdk/x11/gdkdevicemanager-core.c
deleted file mode 100644 (file)
index e332cbc..0000000
+++ /dev/null
@@ -1,909 +0,0 @@
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gdkdevicemanager-core.h"
-
-#include "gdkkeysyms.h"
-#include "gdkdevicemanagerprivate.h"
-#include "gdkdisplayprivate.h"
-#include "gdkeventtranslator.h"
-#include "gdkdevice-core.h"
-#include "gdkprivate-x11.h"
-
-#ifdef HAVE_XKB
-#include <X11/XKBlib.h>
-#endif
-
-
-#define HAS_FOCUS(toplevel)                           \
-  ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
-
-static void    gdk_device_manager_core_finalize    (GObject *object);
-static void    gdk_device_manager_core_constructed (GObject *object);
-
-static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
-                                                     GdkDeviceType     type);
-static GdkDevice * gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager);
-
-static void     gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface);
-
-static gboolean gdk_device_manager_core_translate_event  (GdkEventTranslator *translator,
-                                                          GdkDisplay         *display,
-                                                          GdkEvent           *event,
-                                                          XEvent             *xevent);
-
-
-G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER,
-                         G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
-                                                gdk_device_manager_event_translator_init))
-
-static void
-gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass)
-{
-  GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->finalize = gdk_device_manager_core_finalize;
-  object_class->constructed = gdk_device_manager_core_constructed;
-  device_manager_class->list_devices = gdk_device_manager_core_list_devices;
-  device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer;
-}
-
-static void
-gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface)
-{
-  iface->translate_event = gdk_device_manager_core_translate_event;
-}
-
-static GdkDevice *
-create_core_pointer (GdkDeviceManager *device_manager,
-                     GdkDisplay       *display)
-{
-  return g_object_new (GDK_TYPE_DEVICE_CORE,
-                       "name", "Core Pointer",
-                       "type", GDK_DEVICE_TYPE_MASTER,
-                       "input-source", GDK_SOURCE_MOUSE,
-                       "input-mode", GDK_MODE_SCREEN,
-                       "has-cursor", TRUE,
-                       "display", display,
-                       "device-manager", device_manager,
-                       NULL);
-}
-
-static GdkDevice *
-create_core_keyboard (GdkDeviceManager *device_manager,
-                      GdkDisplay       *display)
-{
-  return g_object_new (GDK_TYPE_DEVICE_CORE,
-                       "name", "Core Keyboard",
-                       "type", GDK_DEVICE_TYPE_MASTER,
-                       "input-source", GDK_SOURCE_KEYBOARD,
-                       "input-mode", GDK_MODE_SCREEN,
-                       "has-cursor", FALSE,
-                       "display", display,
-                       "device-manager", device_manager,
-                       NULL);
-}
-
-static void
-gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
-{
-}
-
-static void
-gdk_device_manager_core_finalize (GObject *object)
-{
-  GdkDeviceManagerCore *device_manager_core;
-
-  device_manager_core = GDK_DEVICE_MANAGER_CORE (object);
-
-  g_object_unref (device_manager_core->core_pointer);
-  g_object_unref (device_manager_core->core_keyboard);
-
-  G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object);
-}
-
-static void
-gdk_device_manager_core_constructed (GObject *object)
-{
-  GdkDeviceManagerCore *device_manager;
-  GdkDisplay *display;
-
-  device_manager = GDK_DEVICE_MANAGER_CORE (object);
-  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
-  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
-  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
-
-  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
-  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
-}
-
-static void
-translate_key_event (GdkDisplay           *display,
-                     GdkDeviceManagerCore *device_manager,
-                    GdkEvent             *event,
-                    XEvent               *xevent)
-{
-  GdkKeymap *keymap = gdk_keymap_get_for_display (display);
-  GdkModifierType consumed, state;
-  gunichar c = 0;
-  gchar buf[7];
-
-  event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
-  event->key.time = xevent->xkey.time;
-  gdk_event_set_device (event, device_manager->core_keyboard);
-
-  event->key.state = (GdkModifierType) xevent->xkey.state;
-  event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
-  event->key.hardware_keycode = xevent->xkey.keycode;
-
-  event->key.keyval = GDK_KEY_VoidSymbol;
-
-  gdk_keymap_translate_keyboard_state (keymap,
-                                      event->key.hardware_keycode,
-                                      event->key.state,
-                                      event->key.group,
-                                      &event->key.keyval,
-                                       NULL, NULL, &consumed);
-
-  state = event->key.state & ~consumed;
-  _gdk_x11_keymap_add_virt_mods (keymap, &state);
-  event->key.state |= state;
-
-  event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
-
-  /* Fill in event->string crudely, since various programs
-   * depend on it.
-   */
-  event->key.string = NULL;
-
-  if (event->key.keyval != GDK_KEY_VoidSymbol)
-    c = gdk_keyval_to_unicode (event->key.keyval);
-
-  if (c)
-    {
-      gsize bytes_written;
-      gint len;
-
-      /* Apply the control key - Taken from Xlib
-       */
-      if (event->key.state & GDK_CONTROL_MASK)
-       {
-         if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
-         else if (c == '2')
-           {
-             event->key.string = g_memdup ("\0\0", 2);
-             event->key.length = 1;
-             buf[0] = '\0';
-             goto out;
-           }
-         else if (c >= '3' && c <= '7') c -= ('3' - '\033');
-         else if (c == '8') c = '\177';
-         else if (c == '/') c = '_' & 0x1F;
-       }
-
-      len = g_unichar_to_utf8 (c, buf);
-      buf[len] = '\0';
-
-      event->key.string = g_locale_from_utf8 (buf, len,
-                                             NULL, &bytes_written,
-                                             NULL);
-      if (event->key.string)
-       event->key.length = bytes_written;
-    }
-  else if (event->key.keyval == GDK_KEY_Escape)
-    {
-      event->key.length = 1;
-      event->key.string = g_strdup ("\033");
-    }
-  else if (event->key.keyval == GDK_KEY_Return ||
-         event->key.keyval == GDK_KEY_KP_Enter)
-    {
-      event->key.length = 1;
-      event->key.string = g_strdup ("\r");
-    }
-
-  if (!event->key.string)
-    {
-      event->key.length = 0;
-      event->key.string = g_strdup ("");
-    }
-
- out:
-#ifdef G_ENABLE_DEBUG
-  if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
-    {
-      g_message ("%s:\t\twindow: %ld    key: %12s  %d",
-                event->type == GDK_KEY_PRESS ? "key press  " : "key release",
-                xevent->xkey.window,
-                event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
-                event->key.keyval);
-
-      if (event->key.length > 0)
-       g_message ("\t\tlength: %4d string: \"%s\"",
-                  event->key.length, buf);
-    }
-#endif /* G_ENABLE_DEBUG */
-  return;
-}
-
-#ifdef G_ENABLE_DEBUG
-static const char notify_modes[][19] = {
-  "NotifyNormal",
-  "NotifyGrab",
-  "NotifyUngrab",
-  "NotifyWhileGrabbed"
-};
-
-static const char notify_details[][23] = {
-  "NotifyAncestor",
-  "NotifyVirtual",
-  "NotifyInferior",
-  "NotifyNonlinear",
-  "NotifyNonlinearVirtual",
-  "NotifyPointer",
-  "NotifyPointerRoot",
-  "NotifyDetailNone"
-};
-#endif
-
-static void
-set_user_time (GdkWindow *window,
-              GdkEvent  *event)
-{
-  g_return_if_fail (event != NULL);
-
-  window = gdk_window_get_toplevel (event->client.window);
-  g_return_if_fail (GDK_IS_WINDOW (window));
-
-  /* If an event doesn't have a valid timestamp, we shouldn't use it
-   * to update the latest user interaction time.
-   */
-  if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
-    gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
-                                  gdk_event_get_time (event));
-}
-
-static void
-generate_focus_event (GdkDeviceManagerCore *device_manager,
-                      GdkWindow            *window,
-                     gboolean              in)
-{
-  GdkEvent *event;
-
-  event = gdk_event_new (GDK_FOCUS_CHANGE);
-  event->focus_change.window = g_object_ref (window);
-  event->focus_change.send_event = FALSE;
-  event->focus_change.in = in;
-  gdk_event_set_device (event, device_manager->core_keyboard);
-
-  gdk_event_put (event);
-  gdk_event_free (event);
-}
-
-static gboolean
-set_screen_from_root (GdkDisplay *display,
-                     GdkEvent   *event,
-                     Window      xrootwin)
-{
-  GdkScreen *screen;
-
-  screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
-
-  if (screen)
-    {
-      gdk_event_set_screen (event, screen);
-
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-static GdkCrossingMode
-translate_crossing_mode (int mode)
-{
-  switch (mode)
-    {
-    case NotifyNormal:
-      return GDK_CROSSING_NORMAL;
-    case NotifyGrab:
-      return GDK_CROSSING_GRAB;
-    case NotifyUngrab:
-      return GDK_CROSSING_UNGRAB;
-    default:
-      g_assert_not_reached ();
-    }
-}
-
-static GdkNotifyType
-translate_notify_type (int detail)
-{
-  switch (detail)
-    {
-    case NotifyInferior:
-      return GDK_NOTIFY_INFERIOR;
-    case NotifyAncestor:
-      return GDK_NOTIFY_ANCESTOR;
-    case NotifyVirtual:
-      return GDK_NOTIFY_VIRTUAL;
-    case NotifyNonlinear:
-      return GDK_NOTIFY_NONLINEAR;
-    case NotifyNonlinearVirtual:
-      return GDK_NOTIFY_NONLINEAR_VIRTUAL;
-    default:
-      g_assert_not_reached ();
-    }
-}
-
-static gboolean
-is_parent_of (GdkWindow *parent,
-              GdkWindow *child)
-{
-  GdkWindow *w;
-
-  w = child;
-  while (w != NULL)
-    {
-      if (w == parent)
-       return TRUE;
-
-      w = gdk_window_get_parent (w);
-    }
-
-  return FALSE;
-}
-
-static GdkWindow *
-get_event_window (GdkEventTranslator *translator,
-                  XEvent             *xevent)
-{
-  GdkDeviceManager *device_manager;
-  GdkDisplay *display;
-  GdkWindow *window;
-
-  device_manager = GDK_DEVICE_MANAGER (translator);
-  display = gdk_device_manager_get_display (device_manager);
-  window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
-
-  /* Apply keyboard grabs to non-native windows */
-  if (xevent->type == KeyPress || xevent->type == KeyRelease)
-    {
-      GdkDeviceGrabInfo *info;
-      gulong serial;
-
-      serial = _gdk_display_get_next_serial (display);
-      info = _gdk_display_has_device_grab (display,
-                                           GDK_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
-                                           serial);
-      if (info &&
-          (!is_parent_of (info->window, window) ||
-           !info->owner_events))
-        {
-          /* Report key event against grab window */
-          window = info->window;
-        }
-    }
-
-  return window;
-}
-
-static gboolean
-gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
-                                         GdkDisplay         *display,
-                                         GdkEvent           *event,
-                                         XEvent             *xevent)
-{
-  GdkDeviceManagerCore *device_manager;
-  GdkWindow *window;
-  GdkWindowImplX11 *window_impl = NULL;
-  gboolean return_val;
-  GdkToplevelX11 *toplevel = NULL;
-  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
-
-  device_manager = GDK_DEVICE_MANAGER_CORE (translator);
-  return_val = FALSE;
-
-  window = get_event_window (translator, xevent);
-
-  if (window)
-    {
-      if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
-        return FALSE;
-
-      toplevel = _gdk_x11_window_get_toplevel (window);
-      window_impl = GDK_WINDOW_IMPL_X11 (window->impl);
-      g_object_ref (window);
-    }
-
-  event->any.window = window;
-  event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
-
-  if (window && GDK_WINDOW_DESTROYED (window))
-    {
-      if (xevent->type != DestroyNotify)
-       {
-         return_val = FALSE;
-         goto done;
-       }
-    }
-
-  if (window &&
-      (xevent->type == MotionNotify ||
-       xevent->type == ButtonRelease))
-    {
-      if (_gdk_x11_moveresize_handle_event (xevent))
-        {
-          return_val = FALSE;
-          goto done;
-        }
-    }
-
-  /* We do a "manual" conversion of the XEvent to a
-   *  GdkEvent. The structures are mostly the same so
-   *  the conversion is fairly straightforward. We also
-   *  optionally print debugging info regarding events
-   *  received.
-   */
-
-  return_val = TRUE;
-
-  switch (xevent->type)
-    {
-    case KeyPress:
-      if (window == NULL)
-        {
-          return_val = FALSE;
-          break;
-        }
-      translate_key_event (display, device_manager, event, xevent);
-      set_user_time (window, event);
-      break;
-
-    case KeyRelease:
-      if (window == NULL)
-        {
-          return_val = FALSE;
-          break;
-        }
-
-      /* Emulate detectable auto-repeat by checking to see
-       * if the next event is a key press with the same
-       * keycode and timestamp, and if so, ignoring the event.
-       */
-
-      if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
-       {
-         XEvent next_event;
-
-         XPeekEvent (xevent->xkey.display, &next_event);
-
-         if (next_event.type == KeyPress &&
-             next_event.xkey.keycode == xevent->xkey.keycode &&
-             next_event.xkey.time == xevent->xkey.time)
-           {
-             return_val = FALSE;
-             break;
-           }
-       }
-
-      translate_key_event (display, device_manager, event, xevent);
-      break;
-
-    case ButtonPress:
-      GDK_NOTE (EVENTS,
-               g_message ("button press:\t\twindow: %ld  x,y: %d %d  button: %d",
-                          xevent->xbutton.window,
-                          xevent->xbutton.x, xevent->xbutton.y,
-                          xevent->xbutton.button));
-
-      if (window == NULL)
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      /* If we get a ButtonPress event where the button is 4 or 5,
-        it's a Scroll event */
-      switch (xevent->xbutton.button)
-        {
-        case 4: /* up */
-        case 5: /* down */
-        case 6: /* left */
-        case 7: /* right */
-         event->scroll.type = GDK_SCROLL;
-
-          if (xevent->xbutton.button == 4)
-            event->scroll.direction = GDK_SCROLL_UP;
-          else if (xevent->xbutton.button == 5)
-            event->scroll.direction = GDK_SCROLL_DOWN;
-          else if (xevent->xbutton.button == 6)
-            event->scroll.direction = GDK_SCROLL_LEFT;
-          else
-            event->scroll.direction = GDK_SCROLL_RIGHT;
-
-         event->scroll.window = window;
-         event->scroll.time = xevent->xbutton.time;
-         event->scroll.x = (gdouble) xevent->xbutton.x;
-         event->scroll.y = (gdouble) xevent->xbutton.y;
-         event->scroll.x_root = (gdouble) xevent->xbutton.x_root;
-         event->scroll.y_root = (gdouble) xevent->xbutton.y_root;
-         event->scroll.state = (GdkModifierType) xevent->xbutton.state;
-         event->scroll.device = device_manager->core_pointer;
-
-         if (!set_screen_from_root (display, event, xevent->xbutton.root))
-           {
-             return_val = FALSE;
-             break;
-           }
-
-          break;
-
-        default:
-         event->button.type = GDK_BUTTON_PRESS;
-         event->button.window = window;
-         event->button.time = xevent->xbutton.time;
-         event->button.x = (gdouble) xevent->xbutton.x;
-         event->button.y = (gdouble) xevent->xbutton.y;
-         event->button.x_root = (gdouble) xevent->xbutton.x_root;
-         event->button.y_root = (gdouble) xevent->xbutton.y_root;
-         event->button.axes = NULL;
-         event->button.state = (GdkModifierType) xevent->xbutton.state;
-         event->button.button = xevent->xbutton.button;
-         event->button.device = device_manager->core_pointer;
-
-         if (!set_screen_from_root (display, event, xevent->xbutton.root))
-            return_val = FALSE;
-
-          break;
-       }
-
-      set_user_time (window, event);
-
-      break;
-
-    case ButtonRelease:
-      GDK_NOTE (EVENTS,
-               g_message ("button release:\twindow: %ld  x,y: %d %d  button: %d",
-                          xevent->xbutton.window,
-                          xevent->xbutton.x, xevent->xbutton.y,
-                          xevent->xbutton.button));
-
-      if (window == NULL)
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      /* We treat button presses as scroll wheel events, so ignore the release */
-      if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
-          xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      event->button.type = GDK_BUTTON_RELEASE;
-      event->button.window = window;
-      event->button.time = xevent->xbutton.time;
-      event->button.x = (gdouble) xevent->xbutton.x;
-      event->button.y = (gdouble) xevent->xbutton.y;
-      event->button.x_root = (gdouble) xevent->xbutton.x_root;
-      event->button.y_root = (gdouble) xevent->xbutton.y_root;
-      event->button.axes = NULL;
-      event->button.state = (GdkModifierType) xevent->xbutton.state;
-      event->button.button = xevent->xbutton.button;
-      event->button.device = device_manager->core_pointer;
-
-      if (!set_screen_from_root (display, event, xevent->xbutton.root))
-        return_val = FALSE;
-
-      break;
-
-    case MotionNotify:
-      GDK_NOTE (EVENTS,
-               g_message ("motion notify:\t\twindow: %ld  x,y: %d %d  hint: %s",
-                          xevent->xmotion.window,
-                          xevent->xmotion.x, xevent->xmotion.y,
-                          (xevent->xmotion.is_hint) ? "true" : "false"));
-
-      if (window == NULL)
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      event->motion.type = GDK_MOTION_NOTIFY;
-      event->motion.window = window;
-      event->motion.time = xevent->xmotion.time;
-      event->motion.x = (gdouble) xevent->xmotion.x;
-      event->motion.y = (gdouble) xevent->xmotion.y;
-      event->motion.x_root = (gdouble) xevent->xmotion.x_root;
-      event->motion.y_root = (gdouble) xevent->xmotion.y_root;
-      event->motion.axes = NULL;
-      event->motion.state = (GdkModifierType) xevent->xmotion.state;
-      event->motion.is_hint = xevent->xmotion.is_hint;
-      event->motion.device = device_manager->core_pointer;
-
-      if (!set_screen_from_root (display, event, xevent->xbutton.root))
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      break;
-
-    case EnterNotify:
-      GDK_NOTE (EVENTS,
-               g_message ("enter notify:\t\twindow: %ld  detail: %d subwin: %ld",
-                          xevent->xcrossing.window,
-                          xevent->xcrossing.detail,
-                          xevent->xcrossing.subwindow));
-
-      if (window == NULL)
-        {
-          return_val = FALSE;
-          break;
-        }
-
-      if (!set_screen_from_root (display, event, xevent->xbutton.root))
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      event->crossing.type = GDK_ENTER_NOTIFY;
-      event->crossing.window = window;
-      gdk_event_set_device (event, device_manager->core_pointer);
-
-      /* If the subwindow field of the XEvent is non-NULL, then
-       *  lookup the corresponding GdkWindow.
-       */
-      if (xevent->xcrossing.subwindow != None)
-       event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
-      else
-       event->crossing.subwindow = NULL;
-
-      event->crossing.time = xevent->xcrossing.time;
-      event->crossing.x = (gdouble) xevent->xcrossing.x;
-      event->crossing.y = (gdouble) xevent->xcrossing.y;
-      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
-      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
-
-      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
-      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
-
-      event->crossing.focus = xevent->xcrossing.focus;
-      event->crossing.state = xevent->xcrossing.state;
-
-      break;
-
-    case LeaveNotify:
-      GDK_NOTE (EVENTS,
-               g_message ("leave notify:\t\twindow: %ld  detail: %d subwin: %ld",
-                          xevent->xcrossing.window,
-                          xevent->xcrossing.detail, xevent->xcrossing.subwindow));
-
-      if (window == NULL)
-        {
-          return_val = FALSE;
-          break;
-        }
-
-      if (!set_screen_from_root (display, event, xevent->xbutton.root))
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      event->crossing.type = GDK_LEAVE_NOTIFY;
-      event->crossing.window = window;
-      gdk_event_set_device (event, device_manager->core_pointer);
-
-      /* If the subwindow field of the XEvent is non-NULL, then
-       *  lookup the corresponding GdkWindow.
-       */
-      if (xevent->xcrossing.subwindow != None)
-       event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
-      else
-       event->crossing.subwindow = NULL;
-
-      event->crossing.time = xevent->xcrossing.time;
-      event->crossing.x = (gdouble) xevent->xcrossing.x;
-      event->crossing.y = (gdouble) xevent->xcrossing.y;
-      event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
-      event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
-
-      event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
-      event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
-
-      event->crossing.focus = xevent->xcrossing.focus;
-      event->crossing.state = xevent->xcrossing.state;
-
-      break;
-
-      /* We only care about focus events that indicate that _this_
-       * window (not a ancestor or child) got or lost the focus
-       */
-    case FocusIn:
-      GDK_NOTE (EVENTS,
-               g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
-                          xevent->xfocus.window,
-                          notify_details[xevent->xfocus.detail],
-                          notify_modes[xevent->xfocus.mode]));
-
-      if (toplevel)
-       {
-         gboolean had_focus = HAS_FOCUS (toplevel);
-
-         switch (xevent->xfocus.detail)
-           {
-           case NotifyAncestor:
-           case NotifyVirtual:
-             /* When the focus moves from an ancestor of the window to
-              * the window or a descendent of the window, *and* the
-              * pointer is inside the window, then we were previously
-              * receiving keystroke events in the has_pointer_focus
-              * case and are now receiving them in the
-              * has_focus_window case.
-              */
-             if (toplevel->has_pointer &&
-                 xevent->xfocus.mode != NotifyGrab &&
-                 xevent->xfocus.mode != NotifyUngrab)
-               toplevel->has_pointer_focus = FALSE;
-
-             /* fall through */
-           case NotifyNonlinear:
-           case NotifyNonlinearVirtual:
-             if (xevent->xfocus.mode != NotifyGrab &&
-                 xevent->xfocus.mode != NotifyUngrab)
-               toplevel->has_focus_window = TRUE;
-             /* We pretend that the focus moves to the grab
-              * window, so we pay attention to NotifyGrab
-              * NotifyUngrab, and ignore NotifyWhileGrabbed
-              */
-             if (xevent->xfocus.mode != NotifyWhileGrabbed)
-               toplevel->has_focus = TRUE;
-             break;
-           case NotifyPointer:
-             /* The X server sends NotifyPointer/NotifyGrab,
-              * but the pointer focus is ignored while a
-              * grab is in effect
-              */
-             if (xevent->xfocus.mode != NotifyGrab &&
-                 xevent->xfocus.mode != NotifyUngrab)
-               toplevel->has_pointer_focus = TRUE;
-             break;
-           case NotifyInferior:
-           case NotifyPointerRoot:
-           case NotifyDetailNone:
-             break;
-           }
-
-         if (HAS_FOCUS (toplevel) != had_focus)
-           generate_focus_event (device_manager, window, TRUE);
-       }
-      break;
-    case FocusOut:
-      GDK_NOTE (EVENTS,
-               g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
-                          xevent->xfocus.window,
-                          notify_details[xevent->xfocus.detail],
-                          notify_modes[xevent->xfocus.mode]));
-
-      if (toplevel)
-       {
-         gboolean had_focus = HAS_FOCUS (toplevel);
-
-         switch (xevent->xfocus.detail)
-           {
-           case NotifyAncestor:
-           case NotifyVirtual:
-             /* When the focus moves from the window or a descendent
-              * of the window to an ancestor of the window, *and* the
-              * pointer is inside the window, then we were previously
-              * receiving keystroke events in the has_focus_window
-              * case and are now receiving them in the
-              * has_pointer_focus case.
-              */
-             if (toplevel->has_pointer &&
-                 xevent->xfocus.mode != NotifyGrab &&
-                 xevent->xfocus.mode != NotifyUngrab)
-               toplevel->has_pointer_focus = TRUE;
-
-             /* fall through */
-           case NotifyNonlinear:
-           case NotifyNonlinearVirtual:
-             if (xevent->xfocus.mode != NotifyGrab &&
-                 xevent->xfocus.mode != NotifyUngrab)
-               toplevel->has_focus_window = FALSE;
-             if (xevent->xfocus.mode != NotifyWhileGrabbed)
-               toplevel->has_focus = FALSE;
-             break;
-           case NotifyPointer:
-             if (xevent->xfocus.mode != NotifyGrab &&
-                 xevent->xfocus.mode != NotifyUngrab)
-               toplevel->has_pointer_focus = FALSE;
-           break;
-           case NotifyInferior:
-           case NotifyPointerRoot:
-           case NotifyDetailNone:
-             break;
-           }
-
-         if (HAS_FOCUS (toplevel) != had_focus)
-           generate_focus_event (device_manager, window, FALSE);
-       }
-      break;
-
-    default:
-        return_val = FALSE;
-    }
-
- done:
-  if (return_val)
-    {
-      if (event->any.window)
-       g_object_ref (event->any.window);
-
-      if (((event->any.type == GDK_ENTER_NOTIFY) ||
-          (event->any.type == GDK_LEAVE_NOTIFY)) &&
-         (event->crossing.subwindow != NULL))
-       g_object_ref (event->crossing.subwindow);
-    }
-  else
-    {
-      /* Mark this event as having no resources to be freed */
-      event->any.window = NULL;
-      event->any.type = GDK_NOTHING;
-    }
-
-  if (window)
-    g_object_unref (window);
-
-  return return_val;
-}
-
-static GList *
-gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
-                                      GdkDeviceType     type)
-{
-  GdkDeviceManagerCore *device_manager_core;
-  GList *devices = NULL;
-
-  if (type == GDK_DEVICE_TYPE_MASTER)
-    {
-      device_manager_core = (GdkDeviceManagerCore *) device_manager;
-      devices = g_list_prepend (devices, device_manager_core->core_keyboard);
-      devices = g_list_prepend (devices, device_manager_core->core_pointer);
-    }
-
-  return devices;
-}
-
-static GdkDevice *
-gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager)
-{
-  GdkDeviceManagerCore *device_manager_core;
-
-  device_manager_core = (GdkDeviceManagerCore *) device_manager;
-  return device_manager_core->core_pointer;
-}
diff --git a/gdk/x11/gdkdevicemanager-core.h b/gdk/x11/gdkdevicemanager-core.h
deleted file mode 100644 (file)
index 774b21e..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GDK_DEVICE_MANAGER_CORE_H__
-#define __GDK_DEVICE_MANAGER_CORE_H__
-
-#include "gdkdevicemanagerprivate.h"
-
-G_BEGIN_DECLS
-
-#define GDK_TYPE_DEVICE_MANAGER_CORE         (gdk_device_manager_core_get_type ())
-#define GDK_DEVICE_MANAGER_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore))
-#define GDK_DEVICE_MANAGER_CORE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
-#define GDK_IS_DEVICE_MANAGER_CORE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE))
-#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE))
-#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
-
-typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore;
-typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass;
-
-struct _GdkDeviceManagerCore
-{
-  GdkDeviceManager parent_object;
-  GdkDevice *core_pointer;
-  GdkDevice *core_keyboard;
-};
-
-struct _GdkDeviceManagerCoreClass
-{
-  GdkDeviceManagerClass parent_class;
-};
-
-GType gdk_device_manager_core_get_type (void) G_GNUC_CONST;
-
-
-G_END_DECLS
-
-#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */
index 25c61005b164415e413d154f5bd98d86a75602b2..026ae769b78988a322742224c334d6321e6aeebd 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "config.h"
 
-#include "gdkdevicemanager-core.h"
+#include "gdkx11devicemanager-core.h"
 #ifdef XINPUT_XFREE
 #include "gdkdevicemanager-xi.h"
 #ifdef XINPUT_2
@@ -79,7 +79,7 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
 
   GDK_NOTE (INPUT, g_print ("Creating core device manager\n"));
 
-  return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
+  return g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_CORE,
                        "display", display,
                        NULL);
 }
index 9433a1fbcdb89f38aa48fceb37a30848310ea500..138d133f36fcc1a87a056a97f3dd3eefa3b4569a 100644 (file)
@@ -57,7 +57,7 @@ static GList *  gdk_device_manager_xi_list_devices     (GdkDeviceManager  *devic
                                                         GdkDeviceType      type);
 
 
-G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI, gdk_device_manager_xi, GDK_TYPE_DEVICE_MANAGER_CORE,
+G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI, gdk_device_manager_xi, GDK_TYPE_X11_DEVICE_MANAGER_CORE,
                          G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
                                                 gdk_device_manager_xi_event_translator_init))
 
index e2028fdb8da982ee1c2a2938251de9924e3b5229..bffa2cbf029b4645358b9b7380752fd1c6cc2659 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef __GDK_DEVICE_MANAGER_XI_H__
 #define __GDK_DEVICE_MANAGER_XI_H__
 
-#include "gdkdevicemanager-core.h"
+#include "gdkx11devicemanager-core.h"
 
 G_BEGIN_DECLS
 
@@ -37,7 +37,7 @@ typedef struct _GdkDeviceManagerXIClass GdkDeviceManagerXIClass;
 
 struct _GdkDeviceManagerXI
 {
-  GdkDeviceManagerCore parent_object;
+  GdkX11DeviceManagerCore parent_object;
   GdkDevice *core_pointer;
   GdkDevice *core_keyboard;
 
@@ -47,7 +47,7 @@ struct _GdkDeviceManagerXI
 
 struct _GdkDeviceManagerXIClass
 {
-  GdkDeviceManagerCoreClass parent_class;
+  GdkX11DeviceManagerCoreClass parent_class;
 };
 
 GType gdk_device_manager_xi_get_type (void) G_GNUC_CONST;
index c8a3f20f680583d36958424610efd28597926d02..f3eef28c3a37c0fcd150f3bd7d1ccb25ce9a7d05 100644 (file)
@@ -56,6 +56,8 @@
 #define __GDKX_H_INSIDE__
 
 #include <gdk/x11/gdkx11cursor.h>
+#include <gdk/x11/gdkx11device-core.h>
+#include <gdk/x11/gdkx11devicemanager-core.h>
 #include <gdk/x11/gdkx11display.h>
 #include <gdk/x11/gdkx11displaymanager.h>
 #include <gdk/x11/gdkx11keys.h>
diff --git a/gdk/x11/gdkx11device-core.h b/gdk/x11/gdkx11device-core.h
new file mode 100644 (file)
index 0000000..e6aea0a
--- /dev/null
@@ -0,0 +1,51 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_X11_DEVICE_CORE_H__
+#define __GDK_X11_DEVICE_CORE_H__
+
+#include "gdkdeviceprivate.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_X11_DEVICE_CORE         (gdk_x11_device_core_get_type ())
+#define GDK_X11_DEVICE_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCore))
+#define GDK_X11_DEVICE_CORE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCoreClass))
+#define GDK_IS_X11_DEVICE_CORE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_CORE))
+#define GDK_IS_X11_DEVICE_CORE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_CORE))
+#define GDK_X11_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCoreClass))
+
+typedef struct _GdkX11DeviceCore GdkX11DeviceCore;
+typedef struct _GdkX11DeviceCoreClass GdkX11DeviceCoreClass;
+
+struct _GdkX11DeviceCore
+{
+  GdkDevice parent_instance;
+};
+
+struct _GdkX11DeviceCoreClass
+{
+  GdkDeviceClass parent_class;
+};
+
+GType gdk_x11_device_core_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GDK_X11_DEVICE_CORE_H__ */
diff --git a/gdk/x11/gdkx11devicemanager-core.h b/gdk/x11/gdkx11devicemanager-core.h
new file mode 100644 (file)
index 0000000..420c7ad
--- /dev/null
@@ -0,0 +1,54 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_X11_DEVICE_MANAGER_CORE_H__
+#define __GDK_X11_DEVICE_MANAGER_CORE_H__
+
+#include "gdkdevicemanagerprivate.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_X11_DEVICE_MANAGER_CORE         (gdk_x11_device_manager_core_get_type ())
+#define GDK_X11_DEVICE_MANAGER_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCore))
+#define GDK_X11_DEVICE_MANAGER_CORE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCoreClass))
+#define GDK_IS_X11_DEVICE_MANAGER_CORE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE))
+#define GDK_IS_X11_DEVICE_MANAGER_CORE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_MANAGER_CORE))
+#define GDK_X11_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCoreClass))
+
+typedef struct _GdkX11DeviceManagerCore GdkX11DeviceManagerCore;
+typedef struct _GdkX11DeviceManagerCoreClass GdkX11DeviceManagerCoreClass;
+
+struct _GdkX11DeviceManagerCore
+{
+  GdkDeviceManager parent_object;
+  GdkDevice *core_pointer;
+  GdkDevice *core_keyboard;
+};
+
+struct _GdkX11DeviceManagerCoreClass
+{
+  GdkDeviceManagerClass parent_class;
+};
+
+GType gdk_x11_device_manager_core_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __GDK_X11_DEVICE_MANAGER_CORE_H__ */